# 基础语法

# 简介

JavaScript 是一种轻量级的脚本语言。脚本语言指的是它不具备开发操作系统的能力,而是只用来编写控制其他大型应用程序(比如浏览器)的“脚本”。

JavaScript 也是一种嵌入式(embedded)语言。它提供的核心语法不算很多,只能用来做一些数学和逻辑运算。JavaScript 本身不提供任何与 I/O(输入/输出)相关的 API,都要靠宿主环境(host)提供,所以它只合适嵌入更大型的应用程序环境,去调用宿主环境提供的底层 API。目前,已经嵌入 JavaScript 的宿主环境有:浏览器Node 服务器环境

从语法角度看,JavaScript 语言是一种“对象模型”语言,还支持函数式编程

JavaScript 的核心语法部分相当精简,只包括两个部分:

  • 基本的语法构造(比如操作符、控制结构、语句)
  • 标准库(就是一系列具有各种功能的对象比如ArrayDateMath等)

各种宿主环境提供额外的 API(即只能在该环境使用的接口),以便 JavaScript 调用。

浏览器提供的额外 API 可以分成三大类:

  • 浏览器控制类:操作浏览器
  • DOM 类:操作网页的各种元素
  • Web 类:实现互联网的各种功能

Node 环境会提供操作系统的 API,比如文件操作 API、网络通信 API等等

组成ECMAScript + BOM + DOM

# 与 HTML 组合

  • 内部引入

    <script>  
    js代码; 
    </script>
    

    在HTML标签中写入<img src="img/1.jpg" id="img1" onclick="javascript:fun2();">

  • 外部引入

    <script src="js/a.js"></script>    <!--  type="text/javascript"可省略  -->
    <script src="js/b.js"></script>
    

TIP

head 中定义的 JavaScript 将会在页面加载前执行,会阻塞页面加载,除非该JS需在网页全部加载完成前就可以调用,否则推荐定义在 </body> 闭合标签之前

Chrome进入 Console 途径:

  • Mac:Command + option + j;Win:Ctrl + Shift + j
  • Mac:Command + option + i;Win:Ctrl + Shift + i再选择 Console 面板

# 数据类型

# 定义

  • undefined(未定义):若变量未初始化则默认值为undefined或直接赋值undefined

  • number(数值):不区分整数和小数、NaN(not a number)。

    所有数字都是以64位浮点数形式储存;位运算只有整数才能完成,此时 JavaScript 会自动转成32位整数,然后运算

  • string(字符串):单引和双引都可以

  • boolean(布尔):true和false

  • null(空):即此处的值为空。一个对象为空的占位符或直接赋值null

    typeof null返回Object,JS最初的错误被ECMAScript沿用。现在 null 被认为是对象的占位符,从而解释了该矛盾

  • object(对象):各种值组成的集合,可以分成三个子类型

    • object(狭义的对象)
    • array(数组)
    • function(函数)

TIP

ES5 只有 6 种,ES6 即 ECMAScript 2015 添加了一种Symbol

通常numberstringboolean这三种类型,合称为原始类型(primitive type)的值,即它们是最基本的数据类型,不能再细分了。对象则称为合成类型(complex type)的值,因为一个对象往往是多个原始类型的值的合成,可以看作是一个存放各种值的容器。

注意小数的计算精度

console.log(0.1 + 0.2 === 0.3); // false
console.log(0.3 / 0.1); // 2.9999999999999996
console.log(0.3 - 0.2 === 0.2 - 0.1); // false

# 判断值的类型

JavaScript 有三种方法,可以确定一个值到底是什么类型。

  • typeof运算符

    console.log(typeof undefiend); // undefiend,用来检查一个没有声明的变量,而不报错。
    console.log(typeof 123); // number
    console.log(typeof "123"); // string
    console.log(typeof false); // boolean
    console.log(typeof null); // object
    console.log(typeof {}); // object
    console.log(typeof [1]); // object
    console.log(typeof function name(params) {}); // function
    
  • instanceof运算符,面向对象使用

  • Object.prototype.toString方法

# 变量

弱类型,区分大小写,但是变量一般都用小写字母开头的驼峰表示法表示

全局变量:在script标签里面定义一个变量,这个变量在页面中js部分都可以使用

  1. 在任何方法之外放置的var语句;var foo = value;
  2. 全局对象添加一个属性windows.foo = value;
  3. 直接使用未经声明的变量(隐式全局变量):foo = value;,不建议使用

局部变量:ES6之前在函数内部定义一个变量,只能在方法内部使用:var foo = value;,其他查看作用域和闭包章节。

声明的提升:详细查看“作用域和闭包中声明的提升章节”,

//原本语句如下:
console.log(a); //不会报错,会输出undefined
var a = 1;

//真正运行的代码如下:
var a;
console.log(a); //会输出undefined,表示a已经声明,但为赋值
a = 1;

# 常量

ES6添加。使用const定义,采取全大写并用下划线分割值不可改变!

# 运算符

# 赋值运算符

=+=-=

# 一元运算符

++(自增)、--(自减)、+(正号,二元运算时可做拼接字符串)、-(负号)

注意:在JS中,一元运算符如果运算数不是运算符所要求的类型,那么js引擎会自动的将运算数进行类型转换

  • stringnumber按照字面值转换。如果字面值不是数字,则转为NaN(不是数字的数字)
  • booleannumbertrue转为1false转为0

# 三元运算符

表达式? 值1:值2;

# 算术运算符

+-*/%(取余,余数趋于0)、**(指数操作,如2^2=4)

# 比较运算符

><>=<======(全等于),比较方式如下:

  • 类型相同直接比较
    • 字符串:按照字典顺序(ASCII)比较。按位逐一比较,直到得出大小为止。
  • 类型不同:先进行类型转换,再比较
    • ==:比较的只是值(会执行类型转换)
    • ===全等于。在比较之前,先判断类型,如果类型不一样,则直接返回false
console.log(undefined == null); // true
console.log(undefined === null); // false

# 逻辑运算符

&&||!

JS 中代表 false的值有(对应数据类型即可记忆):undefined, NaN, 0, "", false, null

其他类型转boolean

  • number0NaN为假,其他为真
  • string:除了空字符串(""),其他都是true。注意空格占位的不是空字符串
  • null&undefined:都是false
  • 对象:所有对象都为true。判断空指针异常(若是字符串都不用判断长度)时直接写if(obj)
console.log(true && "hello");// hello
console.log(false || "default"); // default,可用于默认值
console.log(1 + 2 || "default"); // 3
console.log(!4); // false
console.log(!!4); // true

# 位运算符

&|~^,转为32位二进制补码进行计算

console.log(5 & 3); //1
console.log(5 | 3); //7
console.log(~5); // -6
console.log(5 ^ 3); //6

# 位移运算符

位移运算符不改变原变量数值。输入输出都是对整数类型的二进制补码进行的运算!如下解释以及画图时也应用补码来解释!

  • <<左移,被移除的高位丢弃,低位空缺位补0。当顶替掉符号位时数值正负改变。
  • >>右移,被移位的二进制最高位是0,右移后所有空缺位补0;最高位是1,所有空缺位补1。
  • >>>无符号右移,使用“零扩展”(zero extension),即被移位二进制最高位无论是0或者是1,空缺位都用0补。C/C++ 没有

# 流程控制

  • if...else...(同Java)
  • while...、do...while...(同Java)
  • switch case default
    • Java中switch可以接收的数据类型:byteshortcharintEnum(1.5) 、String(1.7)
    • JavaScript中switch可以接收任意原始数据类型
    • 都有 break 关键字
  • for:var定义的变量不是局部变量,无论布尔表达式是否满足,步进表达式都会执行。所以可以用let来来限制作用范围。
    • for...in:遍历数组或者对象属性for (变量 in 对象)
    • for...of:遍历iterable类型,如ArrayMapSetfor (变量 of 对象)
  • 跳出循环:(breakcontinue只针对最内层循环)
    • break语句用于跳出代码块或循环
    • continue语句用于立即终止本轮循环,返回循环结构的头部,开始下一轮循环
    • label标签通常与break语句和continue语句配合使用,跳出特定的循环
    • return虽然也可以跳出,但是通常用来返回方法

# Other(未整理好)

# 基本类型的包装对象

  • String

    • 创建对象var str = "abc";
    • 属性:length,字符串长度
    • 方法:
    1. 与html相关的方法
      • bold():加粗
      • fontcolor(): 设置字符串的颜色
      • fontsize(): 设置字体的大小
      • link(): 将字符串显示成超链接 str4.link("hello.html")
      • sub() sup(): 下标和上标
    2. 与Java相似的方法
      • concat(): 连接字符串
      • charAt():返回指定指定位置的字符串,若字符位置不存在,返回空字符串
      • indexOf():返回字符串位置
      • split():切分字符串,成数组
      • replace():替换字符串,传递两个参数:原始字符、要替换成的字符
      • substr():从第几位开始,向后截取几位
      • substring()[从第几位开始,到第几位结束)
  • Boolean:var flag = new Boolean(true);,不传值时默认为false

# Global

  • 特点:全局对象,这个Global中封装的方法不需要对象就可以方法名();直接调用

  • 方法:

    • encodeURI():对字符进行url编码,返回另一个字符。不编码字符有82个

    • decodeURI():对字符进行url解码,返回另一个字符

    • encodeURIComponent():对字符进行url编码,编码的字符更多。不编码字符有71个

    • decodeURIComponent():对字符进行url解码

      传智播客 =  %E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2
      
    • parseInt():将字符串转为数字;进制转换 ​ * 逐一判断每一个字符是否是数字,直到不是数字为止,将前边数字部分转为number,第一个也不是数字则为NaN ​ * parseInt('11',2),返回3

    • isNaN():判断一个值是否是NaN - NaN六亲不认,连自己都不认。NaN参与的==比较全部返回false

    • eval():==将JavaScript字符串,作为脚本代码来执行==,若字符串不是脚本代码则不执行

      var str = "alert('1234');";
      alert(str);    //alert('1234');
      eval(str);    //1234
      

# Base64

使用场景

  • 文本里面包含一些不可打印的符号,比如 ASCII 码0到31的符号,可以使用 Base64 编码转成可以打印的字符。
  • 需要以文本格式传递二进制数据,那么也可以使用 Base64 编码。

所谓 Base64 就是一种编码方法,可以将任意值转成 0~9、A~Z、a-z、+/这64个字符组成的可打印字符。使用它的主要目的,不是为了加密,而是为了不出现特殊字符,简化程序的处理。JS提供了如下全局函数

  • btoa():任意值转为 Base64 编码
  • atob():Base64 编码转为原来的值
var str = "hello world";
console.log(btoa(str)); // aGVsbG8gd29ybGQ
console.log(atob("aGVsbG8gd29ybGQ")); // hello world

注意,这两个方法不适合非 ASCII 码的字符,如中文字符,会报错。要将非 ASCII 码字符转为 Base64 编码,必须中间插入一个URL转码环节,JS提供如下全局函数,再使用这两个方法

function b64Encode(str) {
  return btoa(encodeURIComponent(str));
}

function b64Decode(str) {
  return decodeURIComponent(atob(str));
}

console.log(b64Encode("你好")); // "JUU0JUJEJUEwJUU1JUE1JUJE"
console.log(b64Decode("JUU0JUJEJUEwJUU1JUE1JUJE")); // "你好"